/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.frontendproject.zerocode.operation.sourcegenerate;

import com.inspur.edp.web.common.entity.TerminalType;
import com.inspur.edp.web.common.environment.ExecuteEnvironment;
import com.inspur.edp.web.common.io.FileUtility;
import com.inspur.edp.web.frontendproject.zerocode.ZeroCodeParameter;
import com.inspur.edp.web.frontendproject.zerocode.operation.webdevjson.WebDevJsonManager;
import com.inspur.edp.web.jitengine.JITEngineManager;
import com.inspur.edp.web.jitengine.ProjectCompileContext;

/**
 * 零代码 源代码生成调整
 */
abstract class AbstractSourceCodeOperation implements ISourceCodeOperation {

    /**
     * 定义的表单类型
     */
    private final TerminalType terminalType;

    /**
     * 对应的表单类型对应 pc、mobile
     */
    private final String formType;

    /**
     * 使用的框架类型，对应 angular、mobile
     */
    private final String frameworkType;


    AbstractSourceCodeOperation(TerminalType terminalType, String formType, String frameworkType) {
        this.terminalType = terminalType;
        this.formType = formType;
        this.frameworkType = frameworkType;
    }

    /**
     * 获取 webdev 路径
     *
     * @param zeroCodeParameter
     * @return
     */
    protected String getWebDevPath(ZeroCodeParameter zeroCodeParameter) {
        return WebDevJsonManager.getWebDevPath(zeroCodeParameter, this.terminalType);
    }

    /**
     * 判断 webdev json 路径是否存在
     *
     * @param zeroCodeParameter
     * @return
     */
    protected boolean checkWebDevPathExist(ZeroCodeParameter zeroCodeParameter) {
        return FileUtility.exists(this.getWebDevPath(zeroCodeParameter));
    }

    /**
     * 获取生成源代码路径
     *
     * @param zeroCodeParameter
     * @return
     */
    protected String getSourceAppPath(ZeroCodeParameter zeroCodeParameter) {
        return SourceCodePathGenerator.generate(zeroCodeParameter, this.terminalType);
    }




    /**
     * 构造生成上下文参数
     *
     * @param zeroCodeParameter
     * @param formType
     * @param frameworkType
     * @return
     */
    protected ProjectCompileContext generateCompileContext(ZeroCodeParameter zeroCodeParameter, String formType, String frameworkType) {
        String lowerCaseProjectName = this.getLowerCaseProjectName(zeroCodeParameter);
        String webDevPath = this.getWebDevPath(zeroCodeParameter);
        String sourceAppPath = this.getSourceAppPath(zeroCodeParameter);
        ProjectCompileContext projectCompileContext = new ProjectCompileContext(lowerCaseProjectName,
                zeroCodeParameter.getRelyNodeModulesPath(),
                formType, frameworkType,
                webDevPath,
                sourceAppPath, null, zeroCodeParameter.getServiceUnitPath(), ExecuteEnvironment.Runtime);
        if (terminalType == TerminalType.PC) {
            projectCompileContext.setGenerateViewModel(true);
            // 是否使用解析模式
            projectCompileContext.setJieXiForm(zeroCodeParameter.isUseJieXiMode());
        }
        // 零代码不再保留源代码 每次生成前都进行删除
        projectCompileContext.setDeleteSourceCodeBeforeGenerate(true);

        return projectCompileContext;
    }

    @Override
    public void generate(ZeroCodeParameter zeroCodeParameter) {
        if (!this.checkWebDevPathExist(zeroCodeParameter)) {
            return;
        }
        ProjectCompileContext projectCompileContext = this.generateCompileContext(zeroCodeParameter, this.formType, this.frameworkType);
        JITEngineManager.compileProject(projectCompileContext);
    }


    protected String getLowerCaseProjectName(ZeroCodeParameter parameter) {
        return parameter.getProjectName().toLowerCase();
    }
}
